package com.lagou.edu.anno;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Map;

/**
 * 注解类定义器
 */
public class AnnotatedBeanDefinition {

    private Class beanClass;


    /**
     * bean类上的注解 @Component @Service @Controller等
     */
    private Annotation componentAnno;

    private String beanId;

    public AnnotatedBeanDefinition(Class beanClass) {
        this.beanClass = beanClass;
        this.init();

    }

    /**
     * 初始化定义类
     */
    private void init() {
        if (beanClass != null) {
            for (Annotation declaredAnnotation : beanClass.getAnnotations()) {
                // 获取注解的代理处理器
                InvocationHandler invocationHandler = Proxy.getInvocationHandler(declaredAnnotation);
                try {
                    Field type = invocationHandler.getClass().getDeclaredField("type");
                    type.setAccessible(true);
                    // 获取类上的注解
                    Class extAnno = (Class) type.get(invocationHandler);
                    // 含有@Component，或标注了@Component的注解（@Service），则返回成功
                    if (extAnno == MyComponent.class || extAnno.isAnnotationPresent(MyComponent.class)) {
                        this.componentAnno = declaredAnnotation;
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public Annotation getComponentAnno() {
        return componentAnno;
    }

    public Class getBeanClass() {
        return beanClass;
    }

    public String getBeanId() {
        // 1 获取缓存
        if (beanId != null) {
            return beanId;
        }
        // 2 获取注解value值
        if (componentAnno != null) {
            InvocationHandler invocationHandler = Proxy.getInvocationHandler(componentAnno);
            try {
                Field field = invocationHandler.getClass().getDeclaredField("memberValues");
                field.setAccessible(true);
                Map<String, Object> memberValues = (Map<String, Object>) field.get(invocationHandler);
                String value = (String) memberValues.get("value");
                if (value != null && !"".equals(value.trim())) {
                    return beanId = value;
                }
            } catch (Exception e) {
                e.printStackTrace();

            }
        }
        // 3 获取class类名 首字母小写
        String simpleName = this.beanClass.getSimpleName();
        beanId = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1);
        return beanId;
    }

    /**
     * 判断该bean对象是否满足注解扫描加载的要求
     *
     * @return
     */
    public boolean isNeedInjection() {
        // 注解不需要加载
        if (beanClass.isAnnotation()) {
            return false;
        }
        // 没有包含注解@Component的，或者@Service等注解，不需要加载
        Annotation[] classAnnos = beanClass.getAnnotations();
        if (classAnnos.length <= 0) {
            return false;
        }
        if (!isIncloudComponent()) {
            return false;
        }

        // 接口类型不需要加载
        if (beanClass.isInterface()) {
            return false;
        }
        return true;
    }

    /**
     * 判断是否包含注解Component，或者标注了@Component的注解
     *
     * @return
     */
    private boolean isIncloudComponent() {
        return this.componentAnno != null;
    }

    @Override
    public String toString() {
        return "AnnotatedBeanDefinition{" +
                "beanClass=" + beanClass +
                '}';
    }
}
